/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.ec.product.web.ProductAction
   Module Description   :

   Date Created      : 2009/11/23
   Original Author   : ellen.li
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   TODO 1.HTMLeditor 
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.ec.product.web;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang.xwork.StringUtils;
import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.yaodian100.core.admin.entity.Group;
import com.yaodian100.core.admin.entity.Role;
import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.admin.entity.UserPermission;
import com.yaodian100.core.admin.entity.Permission.Type;
import com.yaodian100.core.admin.service.GroupService;
import com.yaodian100.core.admin.service.UserService;
import com.yaodian100.core.admin.utils.AdminHelper;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.entity.SimplePager;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.common.service.DomainService;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.ec.category.entity.Category;
import com.yaodian100.ec.category.service.CategoryService;
import com.yaodian100.ec.common.EcConstant;
import com.yaodian100.ec.image.entity.Image;
import com.yaodian100.ec.image.service.ImageService;
import com.yaodian100.ec.product.entity.AddOnProduct;
import com.yaodian100.ec.product.entity.Brand;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.ProductCategory;
import com.yaodian100.ec.product.entity.ProductPromotionFlag;
import com.yaodian100.ec.product.entity.ProductSupplierApprove;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.entity.SpecificationMajor;
import com.yaodian100.ec.product.entity.Product.IS_SCM;
import com.yaodian100.ec.product.service.Product2Service;
import com.yaodian100.ec.product.service.ProductSupplierApproveService;
import com.yaodian100.ec.shelf.entity.ViewShelf;
import com.yaodian100.ec.supplierapply.entity.SupplierApply;
import com.yaodian100.ec.supplierapply.service.SupplierApplyService;

/**
 * @author ellen.li
 * @param <imageService>
 * 
 */
public class Product3Action extends ActionSupport implements Preparable {

	/**
	 * serial version
	 */
	private static final long serialVersionUID = 817445883772265312L;

	private final Logger logger = LoggerFactory.getLogger(Product2Action.class);
	@Resource
	private Product2Service product2Service;
	@Resource
	private CategoryService categoryService;
	@Resource
	private UserService userService;
	@Resource
	private GroupService groupService;
	@Resource
	private DomainService<Menu> menuService;
	@Resource
	private SupplierApplyService supplierApplyService;
	@Resource
	private ProductSupplierApproveService productSupplierApproveService;
	@Resource
	private ImageService imageService;
	@Resource
	private BaseManager baseMgr;

	/* supplier */
	private String[] supplierDelete;
	private List<Category> categoryRoot;
	private String showSelectedCategory;// 選取的目錄名稱
	private List<ProductCategory> selectedcategories;// 已选的目录
	private String setMainSupplier;// 設為主供應商
	private String[] delSelectedCategory;// 刪除目錄
	private Product product;
	private Specification specification;
	private String productId;
	private List<SpecificationInventory> specificationinventorys;
	private SpecificationInventory specificationinventory;
	private ProductPromotionFlag productPromotionFlag;
	private Map<String, String> fileMap;
	private List<Category> rootCategories;
	private Map<String, String> mapRootCategories;
	private String categoryResult;
	private String jsonCategoryPath;
	private Menu freightMenu;
	private Menu attributeMenu;// 销售状态
	private Menu specStatusMenu;
	private Menu specSubStatusMenu;
	private Menu isScmMenu;// 采购模式
	private Menu dataSrcMenu;// 资料来源
	private Menu expireManageMenu;// 效期管理分类
	private Menu returnRuleMenu;// 退换货条件
	private List<Group> groups;
	private String specStatusParam;
	private String brandName;

	private Map<Long, List<Integer>> specInvMap = new HashMap<Long, List<Integer>>();
	private SupplierApply sp;
	private String spResult = "false";
	private boolean chkHasInventory;
	/* 缺货报表參數 */
	private List<Object> stockReports;
	private String productStParam;
	private String categoryIdParam;
	private String pmIdParam;
	private String isPmGroup;
	private boolean stockNotify;
	private int startStockQty;
	private int endStockQty;
	private String[] productIdBoxs;
	private String arrivalDate;

	/* 分頁 */
	private SimplePager pager;
	private List<Product> products;
	private Map<String, String> rsmap = new HashMap<String, String>();

	/* 商品列表頁參數 */
	private String specCodeParam;// 规格燃号
	private String productNameParam;// 商品名称
	private String productIdParam;// 商品编号
	private String productTypeParam;// 商品型态
	private String categoryLevel1Param;// 馆别
	private String categoryLevel2Param;// 次分类
	private String productAttributeParam;// 销售状态
	private String supplierParam;// 供应商
	private String brandParam;// 品牌
	private String scmParam;// 转单状态
	private String dataSrcParam;// 资料来源
	private String supplierChannel;// 供应商来源
	private String canUseCodYN;// 允许COD付款
	private String largeVolumeProduct;// 大材积商品
	private String productGraphicType;// 主檔图类型
	private String returnRule;// 退换货条件

	/* 商品頁面參數 */
	private String name;
	private String type;
	private String virtual;
	private String cost;
	private String price;
	private String brief;
	private String description;
	private String details;
	private String brand;
	private String tax;
	private String editleadtime;
	private String delivertolerance;
	private String length;
	private String width;
	private String height;
	private String weight;
	private String volume;
	private String unit;
	private String minpo;
	private String maxpo;
	private String temperature;
	private String returnpickup;
	private String returnable;
	private String editsupplier;
	private String editTwSupplier;// 台湾馆供应商
	private String editbrand;
	private String pm;
	private String organization;
	private String[] prdtDelete;
	private String keyword;
	private String editDeliverGeoRange;
	private List<Brand> brands;// 品牌
	private String showSeq;
	private Category category;
	private String orderNotice;
	private String jsonOrderNotice;
	private String expectShipDate;
	private String flag16;
	private String mainCategoryPath;
	private String mainCategoryId;
	private List<User> users;
	private String productAttribute;
	private String supplierCompanyName;
	private String twSupplierCompanyName;
	private String isScm;
	private String scmNotice;
	private String hr24Result;
	private String expireManage;
	private String isAntiUnpacking;
	private String graphicType;
	private int approveSize = 0;
	private List<AddOnProduct> addonsMain = null;
	private List<AddOnProduct> addons = null;
	private List<AddOnProduct> nms = null;
	private String prpsShelfPrice;
	private String copy;
	private String isValidateNum = "N";
	private String useDeliveryDay = "N";
	private int deliveryDay = 0;
	private String tempCategoryFullPath = "";
	private List<Image> descImgs;
	private String saveFlag = "";
	private String nowStep = "1";
	private String canUseCod;
	private String channelFirm;
	private String nmMustOrderBuy;

	/* Spec頁面參數 */
	private int stockQty;
	private Menu mainLabelMenu;
	private Menu secondLabelMenu;
	private String mainLabel;
	private String secondLabel;
	private String mainLabelDefine;
	private String secondLabelDefine;
	private List<SpecificationMajor> majors;
	private String addType;
	private String tempProdSpec;

	/* 主規格列表頁(寫入商品主檔參數) */
	private String mainCodeLabel;
	private String secondCodeLabel;
	private String mainSpecName;
	private String secondSpecName;
	private int hotSaleInventory = 0;

	/* 主次规格 */
	private String[] mainShowSeq;
	private String[] mainDel;
	private String[] majorId;
	private String[] secondDel;
	private String[] majorName;
	private String[] addSpecSel;
	private String[] addMajorSel;

	/* 双属性编辑页面 */
	private SpecificationMajor major;
	private String mainSpecId;
	private String[] spcName;
	private String[] spcId;
	private String[] spcCode;
	private String[] spcBarCode;
	// private String[] spcReverseInventory;
	private String[] spcMaxCountPerOrder;
	private String[] spcMinCountPerOrder;
	private String[] spcSafeInventory;
	private String[] spcDelete;
	private String[] showSpecSeq;
	private String[] spcMajorName;
	private Object[] specifications;
	private Map<String, String> tmpSecondMap;

	/* 商品目录页面参数 */
	private List<ProductCategory> productCategories;
	private Map<Long, String> productCategoryMap;
	private List<ProductCategory> editProductCategories;
	private String finalAddOnData;
	private String categoryId;
	private String jsonAddonProdSpec;
	private String userPermissions = "";
	/* COD商品检核报表 */
	private String salePriceParam;
	private List<ViewShelf> shelfs;

	DateFormat format = new SimpleDateFormat(EcConstant.PATTERN_DATE);

	private String specificId;
	List<Object> orderNoShippingList;
	private Menu orderStMenu;

	public String add() throws CoreException {
		product = new Product();
		product.setShowSeq(101);
		product.setIsScm("B");
		productId = "";
		setBrief("★&nbsp;\n★&nbsp;\n★&nbsp;");
		setDescription("");
		setDetails("");
		setOrderNotice("");
		setScmNotice("");
		setEditsupplier("");
		setEditbrand("");
		setBrandParam("");
		setBrandName("");
		setPm("");
		setOrganization("");
		setEditDeliverGeoRange("");
		setSupplierCompanyName("");
		mainCategoryPath = "";
		setExpireManage("EM01");
		setIsAntiUnpacking("N");
		setGraphicType("S");
		setPrpsShelfPrice("");
		setIsValidateNum("N");
		setReturnRule("07_15");
		setNmMustOrderBuy("N");
		// 清空category相關參數
		tempCategoryFullPath = "";
		mainCategoryId = "";
		flag16 = "";
		setCopy("N");
		return "edit";
	}

	/**
	 * 复制商品
	 * 
	 * @return
	 * @throws Exception
	 */
	public String copy() throws Exception {
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		}
		Product copyProduct = product2Service.get(productId);
		if (null == copyProduct) {
			addActionError("查无商品资料(或无该权限查看)");
			return list();
		}
		copy = "Y";
		product = new Product();
		BeanUtils.copyProperties(copyProduct, product, new String[] { "productId" });
		mainCategoryId = String.valueOf(product.getMainCategoryID());
		mainCategoryPath = product.getCategory().getCategoryPath();
		// 载入分身资料(濾掉主分類資料)
		productCategories = new ArrayList<ProductCategory>();
		Iterator<ProductCategory> iter = product.getProductCategories().iterator();
		while (iter.hasNext()) {
			ProductCategory pc = iter.next();
			if (!pc.getCategoryId().toString().equals(product.getCategory().getId().toString())) {
				productCategories.add(pc);
			}
		}

		productCategoryMap = findProductCategoryMap(productCategories, product);
		User user = AdminHelper.getUser();
		if (null != user) {
			// 若 user 是 PM部門, 檢核 product.category 的 orgnizationPath 是否合乎規定
			int i = 0;
			for (UserPermission up : user.getPermissions(Type.CATEGORY).values()) {
				userPermissions = userPermissions + StringUtils.trim(up.getPermissionCode());
				if (i != user.getPermissions(Type.CATEGORY).values().size() - 1) {
					userPermissions = userPermissions + ",";
				}
				i++;
			}
		}
		brief = product2Service.readFromFile(copyProduct.getProductId(), "brief");
		description = product2Service.readFromFile(copyProduct.getProductId(), "description");
		details = product2Service.readFromFile(copyProduct.getProductId(), "details");
		orderNotice = product2Service.readFromFile(copyProduct.getProductId(), "orderNotice");
		scmNotice = product2Service.readFromFile(copyProduct.getProductId(), "scmNotice");
		isScm = product.getIsScm();
		editsupplier = product.getSupplierId();
		editbrand = StringUtils.defaultString(product.getProductBrand());
		if (null != product.getProductBrand() || StringUtils.isNotBlank(product.getProductBrand())) {
			Brand brand = product2Service.getBrandByBrandId(product.getProductBrand());
			if (null != product2Service.getBrandByBrandId(product.getProductBrand())) {
				brandName = brand.getBrandName();
			} else {
				brandName = "";
			}
		} else {
			brandName = "";
		}
		mainCategoryId = String.valueOf(copyProduct.getMainCategoryID());
		pm = product.getPmID();
		organization = product.getOrganizationPath();
		editDeliverGeoRange = product.getDeliverGeoRange();
		productAttribute = product.getIsDelete();
		returnRule = product.getReturnRule();
		nmMustOrderBuy = product.getNmMustOrderBuy();
		expireManage = product.getExpireManage();
		isAntiUnpacking = product.getIsAntiUnpacking();
		graphicType = product.getGraphicType();
		isValidateNum = product.getIsValidateNum();
		useDeliveryDay = product.getUseDeliveryDay();
		deliveryDay = product.getDeliveryDay();
		if (product.getProductType() == 7) {
			product.setProductType(0);
			type = "0";
		} else {
			type = String.valueOf(product.getProductType());
		}
		if (StringUtils.isNotBlank(product.getChannelFirm())) {
			channelFirm = product.getChannelFirm();
		}
		// 查询已选的主分类详细路径
		if (null != product.getCategory()) {
			tempCategoryFullPath = categoryService.makeCategorieURL(Long.valueOf(product.getMainCategoryID()), false);
		}
		fileMap = new HashMap<String, String>();
		fileMap = readProductFromFile(productId);

		SupplierApply supplierApply = supplierApplyService.get(product.getSupplierId());
		if (null != supplierApply) {
			supplierCompanyName = supplierApply.getCompanyName();
		}
		if (StringUtils.isNotBlank(product.getTwSupplierId())) {
			SupplierApply twSupplierApply = supplierApplyService.get(product.getTwSupplierId());
			if (null != twSupplierApply) {
				editTwSupplier = product.getTwSupplierId();
				twSupplierCompanyName = twSupplierApply.getCompanyName();
			}
		}
		if (null != product.getProductPromotionFlag()) {
			if (StringUtils.isNotBlank(product.getProductPromotionFlag().getFlag16())) {
				flag16 = "true";
			} else {
				flag16 = "";
			}
		}
		productId = "";
		return "edit";
	}

	public String jsonChk24Hr() throws Exception {
		hr24Result = null;
		product = product2Service.get(productId);
		if (Arrays.asList("010000", "010001").contains(product.getSupplierId())) {
			if (StringUtils.isNotBlank(product.getTwSupplierId())) {
				SupplierApply twSupplierApply = supplierApplyService.get(product.getTwSupplierId());
				if (null == twSupplierApply) {
					hr24Result = "台湾馆供应商不存在";
				} else {
					if (!"O".equalsIgnoreCase(twSupplierApply.getBoPoType())) {
						hr24Result = "台湾馆供应商的采购类别为买断时才可修改";
					}
				}
			} else {
				hr24Result = "台湾馆供应商不存在";
			}
		}
		if (StringUtils.isBlank(hr24Result)) {
			CommonCriteria crit = new CommonCriteria();
			crit.addEq("productId", productId);
			crit.addEq("approveStatus", "30");
			List<ProductSupplierApprove> psaList = productSupplierApproveService.getList(0, -1, crit,
					new String[] { "id desc" });
			if (psaList.size() > 0) {
				// 審核成功/失敗後24小時的日期
				Date hr24 = DateUtils.addDays(psaList.get(0).getApproveDate(), 1);
				if (new Date().before(hr24)) {
					hr24Result = "24小时内不可再异动";
				}
			}
		}
		return "jsonChk24Hr";
	}

	/* 編輯商品 */
	public String edit() throws Exception {
		mainCategoryPath = "";
		mainCategoryId = "";
		product = null;
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		}
		product = product2Service.get(productId);
		if (null == product) {
			addActionError("查无商品资料(或无该权限查看)");
			return list();
		}
		// 载入分身资料(濾掉主分類資料)
		productCategories = new ArrayList<ProductCategory>();
		Iterator<ProductCategory> iter = product.getProductCategories().iterator();
		while (iter.hasNext()) {
			ProductCategory pc = iter.next();
			if (!pc.getCategoryId().toString().equals(product.getCategory().getId().toString())) {
				productCategories.add(pc);
			}
		}

		productCategoryMap = findProductCategoryMap(productCategories, product);
		User user = AdminHelper.getUser();
		if (null != user) {
			// 若 user 是 PM部門, 檢核 product.category 的 orgnizationPath 是否合乎規定
			int i = 0;
			for (UserPermission up : user.getPermissions(Type.CATEGORY).values()) {
				userPermissions = userPermissions + StringUtils.trim(up.getPermissionCode());
				if (i != user.getPermissions(Type.CATEGORY).values().size() - 1) {
					userPermissions = userPermissions + ",";
				}
				i++;
			}
		}

		// 搭售主商品
		CommonCriteria crit = new CommonCriteria();
		crit = new CommonCriteria();
		crit.addEq("mainProductId", product.getProductId());
		crit.addGe("addOnPrice", new BigDecimal(0));
		crit.addEq("isDelete", "N");
		crit.addLe("startDate", new Date());
		crit.addGe("endDate", new Date());
		addonsMain = product2Service.getAddOnProductList(0, -1, crit, null);

		// 搭售次商品
		crit = new CommonCriteria();
		crit.addEq("addOnProductId", product.getProductId());
		crit.addGe("addOnPrice", new BigDecimal(0));
		crit.addEq("isDelete", "N");
		crit.addLe("startDate", new Date());
		crit.addGe("endDate", new Date());
		addons = product2Service.getAddOnProductList(0, -1, crit, null);

		// n选m搭售商品
		crit = new CommonCriteria();
		crit.addEq("addOnProductId", product.getProductId());
		crit.addGe("addOnPrice", new BigDecimal(-1));
		crit.addEq("isDelete", "N");
		crit.addLe("startDate", new Date());
		crit.addGe("endDate", new Date());
		nms = product2Service.getAddOnProductList(0, -1, crit, null);

		if (StringUtils.isBlank(product.getIsScm())) {// 预设为PO
			isScm = StringUtils.defaultString(product.getIsScm(), "N");
		}

		// 供应商审核状态
		crit = new CommonCriteria();
		crit.addEq("productId", product.getProductId());
		crit.addEq("approveStatus", "10");
		approveSize = productSupplierApproveService.getListSize(crit).intValue();

		// 确认商品是否有库存
		chkHasInventory = product2Service.chkProductHasInventory(product);

		// 载入商品描述、规格参数、购物须知、特殊商品购物须知
		Map<String, String> fileMap = readProductFromFile(productId);
		if (!fileMap.isEmpty()) {
			setBrief(fileMap.get("brief"));
			setDescription(fileMap.get("description"));
			setDetails(fileMap.get("details"));
			setOrderNotice(fileMap.get("orderNotice"));
			setScmNotice(fileMap.get("scmNotice"));
		}

		// 设定载入的初始化资料
		setCopy("N");
		setEditsupplier(product.getSupplierId());
		setEditbrand(StringUtils.defaultString(product.getProductBrand()));
		if (StringUtils.isNotBlank(product.getProductBrand())) {
			Brand brand = product2Service.getBrandByBrandId(product.getProductBrand());
			if (null != product2Service.getBrandByBrandId(product.getProductBrand())) {
				setBrandName(brand.getBrandName());
			} else {
				setBrandName("");
			}
		} else {
			setBrandName("");
		}
		setPm(product.getPmID());
		setOrganization(product.getOrganizationPath());
		setEditDeliverGeoRange(product.getDeliverGeoRange());
		setProductAttribute(product.getIsDelete());
		setReturnRule(product.getReturnRule());
		setNmMustOrderBuy(product.getNmMustOrderBuy());
		setIsScm(product.getIsScm());
		setExpireManage(product.getExpireManage());
		setIsAntiUnpacking(product.getIsAntiUnpacking());
		setGraphicType(product.getGraphicType());
		setIsValidateNum(product.getIsValidateNum());
		setUseDeliveryDay(product.getUseDeliveryDay());
		setDeliveryDay(product.getDeliveryDay());
		// 供应商公司名称
		SupplierApply supplierApply = supplierApplyService.get(product.getSupplierId());
		if (null != supplierApply) {
			supplierCompanyName = supplierApply.getCompanyName();
		}
		// 台湾馆供应商公司名称
		if (StringUtils.isNotBlank(product.getTwSupplierId())) {
			SupplierApply twSupplierApply = supplierApplyService.get(product.getTwSupplierId());
			if (null != twSupplierApply) {
				editTwSupplier = product.getTwSupplierId();
				twSupplierCompanyName = twSupplierApply.getCompanyName();
			}
		}

		// 查询已选的主分类详细路径
		if (null != product.getCategory()) {
			tempCategoryFullPath = categoryService.makeCategorieURL(Long.valueOf(product.getMainCategoryID()), false);
			mainCategoryPath = product.getCategory().getCategoryPath();
			mainCategoryId = String.valueOf(product.getMainCategoryID());

		}

		productPromotionFlag = product2Service.getProductPromotionFlag(productId);
		if (null != productPromotionFlag) {
			if (StringUtils.isNotBlank(productPromotionFlag.getFlag16())) {
				flag16 = "true";
			} else {
				flag16 = "";
			}
		}
		nowStep = "1";
		return "edit";
	}

	/**
	 * 修改商品属性
	 * 
	 * @return
	 * @throws Exception
	 */
	public String editProductAttribute() throws Exception {
		if (prdtDelete != null) {
			for (int i = 0; i < prdtDelete.length; i++) {
				product = product2Service.get(prdtDelete[i]);
				product.setIsDelete(productAttribute);
				product2Service.update(product);
			}
		}
		return list();
	}

	// 若该商品已被列入搭售时,规格只能有一个,不可以再新增规格
	public String findAddonProdSpec() throws Exception {
		if (StringUtils.isNotBlank(productId)) {
			CommonCriteria crit = new CommonCriteria();
			crit.addEq("addOnProductId", productId);
			crit.addEq("isEnable", "Y");
			crit.addEq("isDelete", "N");
			int iAddOnSpec = product2Service.getAddOnProductList(0, -1, crit, null).size();
			if (iAddOnSpec > 0) {
				jsonAddonProdSpec = "canOnlyOneSpec";
			} else {
				jsonAddonProdSpec = "canMoreSpec";
			}
		}
		return "jsonFindAddonProdSpec";
	}

	public String findCategoryPath() throws Exception {
		if (StringUtils.isNotBlank(categoryId)) {
			Long tempCategoryId = Long.parseLong(categoryId);
			jsonCategoryPath = categoryService.get(tempCategoryId).getCategoryPath();
		}
		return "jsonFindCategoryPath";
	}

	public String findSupplierApply() throws Exception {
		if (StringUtils.isNotBlank(editsupplier)) {
			sp = supplierApplyService.get(editsupplier);
			if (StringUtils.isNotBlank(sp.getShipAddr()) && StringUtils.isNotBlank(sp.getShipProvince())
					&& StringUtils.isNotBlank(sp.getShipCity()) && StringUtils.isNotBlank(sp.getShipArea())
					&& StringUtils.isNotBlank(sp.getShipContact()) && StringUtils.isNotBlank(sp.getShipZip())
					&& StringUtils.isNotBlank(sp.getShipPhone())) {
				spResult = "true," + sp.getIsScm();
			} else {
				spResult = "false," + sp.getIsScm();
			}
		} else {
			spResult = "false," + sp.getIsScm();
		}
		return "jsonFindSupplierApply";
	}

	Map<Long, String> findProductCategoryMap(List<ProductCategory> productCategories, Product product)
			throws CoreException {
		productCategoryMap = new HashMap<Long, String>();
		for (ProductCategory productCategory : productCategories) {
			productCategoryMap.put(productCategory.getCategoryId(), categoryService.makeCategorieURL(productCategory
					.getCategoryId(), false)
					+ "," + productCategory.getCategoryPath() + "," + productCategory.getShowSeq());
		}
		return productCategoryMap;
	}

	public Menu getAttributeMenu() {
		return attributeMenu;
	}

	/**
	 * @return the band
	 */
	public String getBrand() {
		return brand;
	}

	public String getBrandName() {
		return brandName;
	}

	public String getBrandParam() {
		return brandParam;
	}

	/**
	 * @return the brands
	 */
	public List<Brand> getBrands() {
		return brands;
	}

	/**
	 * @return the brief
	 */
	public String getBrief() {
		return brief;
	}

	public Category getCategory() {
		return category;
	}

	public String getCategoryId() {
		return categoryId;
	}

	public String getCategoryIdParam() {
		return categoryIdParam;
	}

	public String getCategoryLevel1Param() {
		return categoryLevel1Param;
	}

	public String getCategoryLevel2Param() {
		return categoryLevel2Param;
	}

	public String getCategoryResult() {
		return categoryResult;
	}

	/**
	 * @return the categoryRoot
	 */
	public List<Category> getCategoryRoot() {
		return categoryRoot;
	}

	/**
	 * @return the categoryService
	 */
	public CategoryService getCategoryService() {
		return categoryService;
	}

	/**
	 * @return the cost
	 */
	public String getCost() {
		return cost;
	}

	/**
	 * @return the delivertolerance
	 */
	public String getDelivertolerance() {
		return delivertolerance;
	}

	/**
	 * @return the delSelectedCategory
	 */
	public String[] getDelSelectedCategory() {
		return delSelectedCategory;
	}

	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}

	/**
	 * @return the details
	 */
	public String getDetails() {
		return details;
	}

	public String getEditbrand() {
		return editbrand;
	}

	/**
	 * @return the editDeliverGeoRange
	 */
	public String getEditDeliverGeoRange() {
		return editDeliverGeoRange;
	}

	/**
	 * @return the editleadtime
	 */
	public String getEditleadtime() {
		return editleadtime;
	}

	public List<ProductCategory> getEditProductCategories() {
		return editProductCategories;
	}

	/**
	 * @return the editsupplier
	 */
	public String getEditsupplier() {
		return editsupplier;
	}

	public String getExpectShipDate() {
		return expectShipDate;
	}

	public Map<String, String> getFileMap() {
		return fileMap;
	}

	public String getFinalAddOnData() {
		return finalAddOnData;
	}

	public String getFlag16() {
		return flag16;
	}

	public Menu getFreightMenu() {
		return freightMenu;
	}

	public List<Group> getGroups() {
		return groups;
	}

	/**
	 * @return the height
	 */
	public String getHeight() {
		return height;
	}

	public String getIsPmGroup() {
		return isPmGroup;
	}

	public String getJsonAddonProdSpec() {
		return jsonAddonProdSpec;
	}

	/**
	 * 判断是否为最底层的目录
	 * 
	 * @return
	 * @throws CoreException
	 */
	public String getJsonCategoryData() throws CoreException {
		category = categoryService.get(Long.parseLong(mainCategoryId));
		categoryResult = category.getIsEndnode();
		return "jsonCategoryData";
	}

	public String getJsonCategoryPath() {
		return jsonCategoryPath;
	}

	public String getJsonOrderNotice() {
		return jsonOrderNotice;
	}

	/**
	 * @return the keyword
	 */
	public String getKeyword() {
		return keyword;
	}

	/**
	 * @return the length
	 */
	public String getLength() {
		return length;
	}

	public String getMainCategoryId() {
		return mainCategoryId;
	}

	public Map<String, String> getMapRootCategories() {
		return mapRootCategories;
	}

	/**
	 * @return the maxpo
	 */
	public String getMaxpo() {
		return maxpo;
	}

	/**
	 * @return the minpo
	 */
	public String getMinpo() {
		return minpo;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	public String getOrderNotice() {
		return orderNotice;
	}

	/**
	 * @return the organization
	 */
	public String getOrganization() {
		return organization;
	}

	/**
	 * @return the pager
	 */
	public SimplePager getPager() {
		return pager;
	}

	/**
	 * @return the pm
	 */
	public String getPm() {
		return pm;
	}

	public String getPmIdParam() {
		return pmIdParam;
	}

	/**
	 * @return the prdtDelete
	 */
	public String[] getPrdtDelete() {
		return prdtDelete;
	}

	/**
	 * @return the price
	 */
	public String getPrice() {
		return price;
	}

	/**
	 * @return the product
	 */
	public Product getProduct() {
		return product;
	}

	public String getProductAttribute() {
		return productAttribute;
	}

	public String getProductAttributeParam() {
		return productAttributeParam;
	}

	public List<ProductCategory> getProductCategories() {
		return productCategories;
	}

	public Map<Long, String> getProductCategoryMap() {
		return productCategoryMap;
	}

	/**
	 * @return the productId
	 */
	public String getProductId() {
		return productId;
	}

	/**
	 * @return the productIdParam
	 */
	public String getProductIdParam() {
		return productIdParam;
	}

	/**
	 * @return the productNameParam
	 */
	public String getProductNameParam() {
		return productNameParam;
	}

	public ProductPromotionFlag getProductPromotionFlag() {
		return productPromotionFlag;
	}

	/**
	 * @return the products
	 */
	public List<Product> getProducts() {
		return products;
	}

	/**
	 * @return the productService
	 */
	public Product2Service getProduct2Service() {
		return product2Service;
	}

	public String getProductStParam() {
		return productStParam;
	}

	public String getProductTypeParam() {
		return productTypeParam;
	}

	/**
	 * @return the returnable
	 */
	public String getReturnable() {
		return returnable;
	}

	/**
	 * @return the returnpickup
	 */
	public String getReturnpickup() {
		return returnpickup;
	}

	public List<Category> getRootCategories() {
		return rootCategories;
	}

	/**
	 * @return the rsmap
	 */
	public Map<String, String> getRsmap() {
		return rsmap;
	}

	/**
	 * @return the selectedcategories
	 */
	public List<ProductCategory> getSelectedcategories() {
		return selectedcategories;
	}

	public String getSetMainSupplier() {
		return setMainSupplier;
	}

	/**
	 * @return the showSelectedCategory
	 */
	public String getShowSelectedCategory() {
		return showSelectedCategory;
	}

	public String getShowSeq() {
		return showSeq;
	}

	public String[] getShowSpecSeq() {
		return showSpecSeq;
	}

	/**
	 * @return the spcBarCode
	 */
	public String[] getSpcBarCode() {
		return spcBarCode;
	}

	/**
	 * @return the spcCode
	 */
	public String[] getSpcCode() {
		return spcCode;
	}

	/**
	 * @return the spcDelete
	 */
	public String[] getSpcDelete() {
		return spcDelete;
	}

	/**
	 * @return the spcId
	 */
	public String[] getSpcId() {
		return spcId;
	}

	/**
	 * @return the spcMaxCountPerOrder
	 */
	public String[] getSpcMaxCountPerOrder() {
		return spcMaxCountPerOrder;
	}

	/**
	 * @return the spcMinCountPerOrder
	 */
	public String[] getSpcMinCountPerOrder() {
		return spcMinCountPerOrder;
	}

	/**
	 * @return the spcName
	 */
	public String[] getSpcName() {
		return spcName;
	}

	// /**
	// * @return the spcReverseInventory
	// */
	// public String[] getSpcReverseInventory() {
	// return spcReverseInventory;
	// }

	/**
	 * @return the spcSafeInventory
	 */
	public String[] getSpcSafeInventory() {
		return spcSafeInventory;
	}

	/**
	 * @return the specification
	 */
	public Specification getSpecification() {
		return specification;
	}

	/**
	 * @return the specificationinventory
	 */
	public SpecificationInventory getSpecificationinventory() {
		return specificationinventory;
	}

	/**
	 * @return the specificationinventorys
	 */
	public List<SpecificationInventory> getSpecificationinventorys() {
		return specificationinventorys;
	}

	public Menu getSpecStatusMenu() {
		return specStatusMenu;
	}

	public String getSpecStatusParam() {
		return specStatusParam;
	}

	public Menu getSpecSubStatusMenu() {
		return specSubStatusMenu;
	}

	public List<Object> getStockReports() {
		return stockReports;
	}

	public SupplierApplyService getSupplierApplyService() {
		return supplierApplyService;
	}

	public String getSupplierCompanyName() {
		return supplierCompanyName;
	}

	/**
	 * @return the supplierDelete
	 */
	public String[] getSupplierDelete() {
		return supplierDelete;
	}

	public String getSupplierParam() {
		return supplierParam;
	}

	/**
	 * @return the tax
	 */
	public String getTax() {
		return tax;
	}

	/**
	 * @return the temperature
	 */
	public String getTemperature() {
		return temperature;
	}

	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}

	/**
	 * @return the unit
	 */
	public String getUnit() {
		return unit;
	}

	public List<User> getUsers() {
		return users;
	}

	/**
	 * @return the virtual
	 */
	public String getVirtual() {
		return virtual;
	}

	/**
	 * @return the volume
	 */
	public String getVolume() {
		return volume;
	}

	/**
	 * @return the weight
	 */
	public String getWeight() {
		return weight;
	}

	/**
	 * @return the width
	 */
	public String getWidth() {
		return width;
	}

	/* 商品列表 */
	public String list() throws Exception {
		String categoryPathParam = "";
		if (StringUtils.isNotBlank(categoryLevel1Param) && StringUtils.isNotBlank(categoryLevel2Param)) {
			categoryPathParam = categoryLevel1Param + "/" + categoryLevel2Param;
		} else if (StringUtils.isNotBlank(categoryLevel1Param) && StringUtils.isBlank(categoryLevel2Param)) {
			categoryPathParam = categoryLevel1Param + "/";
		}
		Map<String, String> searchMap = new HashMap<String, String>();
		searchMap.put("productId", productIdParam);
		searchMap.put("productName", productNameParam);
		searchMap.put("isDelete", productAttributeParam);
		searchMap.put("productType", productTypeParam);
		searchMap.put("supplierId", supplierParam);
		searchMap.put("categoryPath", categoryPathParam);
		searchMap.put("productBrand", brandParam);
		searchMap.put("isScm", scmParam);
		searchMap.put("dataSrc", dataSrcParam);
		searchMap.put("channelFirm", supplierChannel);
		searchMap.put("canUseCod", canUseCodYN);
		searchMap.put("largeVolumeProduct", largeVolumeProduct);
		searchMap.put("graphicType", productGraphicType);
		searchMap.put("returnRule", returnRule);
		searchMap.put("specCodeParam", specCodeParam);
		long entitySize = product2Service.getProductPageableListSize(searchMap).longValue();
		pager.setTotalSize(entitySize);
		products = product2Service.getProductPageableList(searchMap, pager.getCurrentPage() * pager.getPageRecord(), pager
				.getPageRecord());

		// 取得商品可購數
		if (null != products) {
			rsmap = product2Service.getSpecificationinventoryDaoSum(products);
		}
		return "list";
	}

	/**
	 * 动态载入购物须知
	 * 
	 * @return
	 * @throws CoreException
	 */
	public String loadOrderNotice() throws CoreException {
		category = categoryService.get(Long.parseLong(categoryId));

		if (category.getLevel() == "0") {
			jsonOrderNotice = product2Service.readOrderNotice(categoryId);
		} else {
			jsonOrderNotice = product2Service.readOrderNotice(category.getCategoryPath().split("/")[0]);
		}
		return "jsonLoadOrderNotice";
	}

	public void prepare() throws Exception {
		clearErrorsAndMessages();
		if (pager == null) {
			pager = new SimplePager();
		}
		pager.setPageRecord(20);// defaut 20

		if (null == rootCategories) {
			rootCategories = categoryService.getChild(0l);
			mapRootCategories = new HashMap<String, String>();
			for (Category rootCategory : rootCategories) {
				mapRootCategories.put(rootCategory.getId().toString(), rootCategory.getName());
			}
		}

		// 找出所有ｐｍ的user
		if (null == users) {
			users = userService.getByRole(Role.Default.PM.name(), Role.Type.OTHER);
		}

		// 运送区域
		if (null == freightMenu) {
			freightMenu = menuService.get("Freight.key");
		}

		// 找出a-20的部門
		groups = groupService.getList(0, -1, new CommonCriteria().addRlike("code", EcConstant.PRODUCT_PM_GROUP_CODE),
				new String[] { "code" });

		// 商品属性
		attributeMenu = menuService.get("Product.Attribute");

		// 规格属性
		specStatusMenu = menuService.get("Spec.Status");

		// 规格状态
		if (null == specSubStatusMenu) {
			specSubStatusMenu = menuService.get("Specification.SpecStatus");
		}

		// 效期管理分类
		if (null == expireManageMenu) {
			expireManageMenu = menuService.get("ExpireManage.Attribute");
		}

		// 退换货条件
		returnRuleMenu = menuService.get("Order.ReturnRule");

		if (null == orderStMenu) {
			orderStMenu = menuService.get("Order.status.md");
		}

		// 主规格标签
		if (null == mainLabelMenu) {
			mainLabelMenu = menuService.get("Spec.MainLabel");
		}

		// 次规格标签
		if (null == secondLabelMenu) {
			secondLabelMenu = menuService.get("Spec.SecondLabel");
		}

		// 采购模式
		if (null == isScmMenu) {
			isScmMenu = menuService.get("Product.isScm");
		}

		// 资料来源
		if (null == dataSrcMenu) {
			dataSrcMenu = menuService.get("Product.dataSrc");
		}

		if (StringUtils.isNotBlank(productIdParam)) {
			setProductIdParam(productIdParam);
		}
		if (StringUtils.isNotBlank(productNameParam)) {
			setProductNameParam(productNameParam);
		}
		if (StringUtils.isNotBlank(productAttributeParam)) {
			setProductAttributeParam(productAttributeParam);
		}
		if (StringUtils.isNotBlank(productTypeParam)) {
			setProductTypeParam(productTypeParam);
		}
		if (StringUtils.isNotBlank(specStatusParam)) {
			setSpecStatusParam(specStatusParam);
		} else {
			setSpecStatusParam("N");
		}
		if (StringUtils.isNotBlank(categoryLevel1Param)) {
			setCategoryLevel1Param(categoryLevel1Param);
		}
		if (StringUtils.isNotBlank(categoryLevel2Param)) {
			setCategoryLevel2Param(categoryLevel2Param);
		}
		if (StringUtils.isNotBlank(supplierParam)) {
			setSupplierParam(supplierParam);
		}
		if (StringUtils.isNotBlank(brandParam)) {
			setBrandParam(brandParam);
		}
		stockQty = 0;
		userPermissions = "";
		productCategories = null;
		majors = null;
		saveFlag = "";
	}

	/**
	 * 读商品活动简介／特色、商品活动说明文字、商品活动规格内容檔案
	 * 
	 * @param product
	 * @return
	 * @throws CoreException
	 */
	Map<String, String> readProductFromFile(String productId) throws CoreException {
		Map<String, String> tempMap = new HashMap<String, String>();
		tempMap.put("brief", product2Service.readFromFile(productId, "brief"));
		tempMap.put("description", product2Service.readFromFile(productId, "description"));
		tempMap.put("details", product2Service.readFromFile(productId, "details"));
		tempMap.put("orderNotice", product2Service.readFromFile(productId, "orderNotice"));
		tempMap.put("scmNotice", product2Service.readFromFile(productId, "scmNotice"));
		return tempMap;
	}

	/**
	 * 儲存商品資料
	 * 
	 * @return
	 * @throws Exception
	 */
	public String save() throws Exception {
		final BigDecimal tempBigDecimal = new BigDecimal(0).setScale(2, BigDecimal.ROUND_FLOOR);
		/* 商品存檔前栏位检查 */
		if (StringUtils.isNotBlank(productId)) {
			if (null == product || !StringUtils.equals(productId, product.getProductId())) {
				addActionError("查无商品资料(或无该权限查看)");
				return "edit";
			}
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return "edit";
			}
			// 中台在設定預購時是不是要檢查是否有設定N選M or 搭售
			if (StringUtils.equals("1", type)) {
				Long addonsCount = baseMgr
						.countByHql(
								"from AddOnProduct where isDelete = 'N' and sysdate between startDate and endDate and ( mainProductId = ? or addOnProductId = ? )",
								new Object[] { productId, productId });
				if (addonsCount > 0) {
					addActionError("商品不可设为预购，已存在于N選M or 搭售");
					return "edit";
				}
			}
			if (null == product.getProductPromotionFlag()) {
				productPromotionFlag = new ProductPromotionFlag();
			} else {
				productPromotionFlag = product.getProductPromotionFlag();
			}
			if (product.getStepFlag() == 1) {
				product.setStepFlag(2);
			}
		} else {
			// 新增时才可写入商品成本,修改时不允许异动
			product = new Product();
			productPromotionFlag = new ProductPromotionFlag();
			product.setStepFlag(2);
			if (StringUtils.isBlank(cost)) {
				product.setProductCost(new BigDecimal(0).setScale(2, BigDecimal.ROUND_FLOOR));
			} else {
				product.setProductCost(new BigDecimal(cost).setScale(2, BigDecimal.ROUND_FLOOR));
			}
		}
		if (StringUtils.isBlank(mainCategoryId)) {
			addActionError("主分类资料不得为空");
			return "edit";
		} else {
			category = categoryService.get(Long.valueOf(mainCategoryId));
			if (null == category || category.getIsDelete().equalsIgnoreCase("Y")) {
				addActionError("儲存失敗,主分类资料不正确");
				return "edit";
			}
			product.setMainCategoryID(Integer.valueOf(mainCategoryId));
			product.setMainCategoryPath(category.getCategoryPath());
			product.setCategory(category);
		}

		if (StringUtils.isNotBlank(name)) {
			product.setProductName(name);
		}
		product.setProductType(Integer.valueOf(type));
		product.setIsVirtual(virtual);
		if (StringUtils.isNotBlank(isScm)) {
			product.setIsScm(isScm);
			if (StringUtils.equalsIgnoreCase(IS_SCM.SCM.getValue(), isScm)) {
				product.setCanUseCod("Y");
			} else {
				product.setCanUseCod(canUseCod);
			}
		}
		product.setListPrice(new BigDecimal(price).setScale(1, BigDecimal.ROUND_FLOOR));
		if (StringUtils.isNotBlank(tax)) {
			product.setTaxClass(tax);
		} else {
			product.setTaxClass("0");
		}
		if (StringUtils.isNotBlank(editleadtime)) {
			product.setLeadTime(Integer.valueOf(editleadtime));
		}

		if (StringUtils.isNotBlank(delivertolerance)) {
			product.setIsDeliverTolerance(delivertolerance);
		} else {
			product.setIsDeliverTolerance("N");
		}

		product.setDeliverGeoRange(editDeliverGeoRange);
		if (StringUtils.isNotBlank(length)) {
			product.setProductLength(new BigDecimal(length).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setProductLength(tempBigDecimal);
		}

		if (StringUtils.isNotBlank(width)) {
			product.setProductWidth(new BigDecimal(width).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setProductWidth(tempBigDecimal);
		}

		if (StringUtils.isNotBlank(height)) {
			product.setProductHeight(new BigDecimal(height).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setProductHeight(tempBigDecimal);
		}

		if (StringUtils.isNotBlank(weight)) {
			product.setProductWeight(new BigDecimal(weight).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setProductWeight(tempBigDecimal);
		}

		if (StringUtils.isNotBlank(volume)) {
			product.setProductVolume(new BigDecimal(volume).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setProductVolume(tempBigDecimal);
		}

		product.setProductUnit(unit);
		if (!"0".equals(minpo)) {
			product.setMinPOQuantity(Integer.valueOf(minpo));
		}
		if (!"0".equals(maxpo)) {
			product.setMaxPOQuantity(Integer.valueOf(maxpo));
		}
		if (!"0".equals(temperature)) {
			product.setTemperatureType(Integer.valueOf(temperature));
		}

		if (StringUtils.isNotBlank(returnpickup)) {
			product.setIsReturnPickup(returnpickup);
		} else {
			product.setIsReturnPickup("Y");
		}

		if (StringUtils.isNotBlank(returnable)) {
			product.setIsReturnable(returnable);
		} else {
			product.setIsReturnable("Y");
		}

		if (StringUtils.isNotBlank(expireManage)) {
			product.setExpireManage(expireManage);
		} else {
			product.setExpireManage("EM01");
		}

		if (StringUtils.isNotBlank(isAntiUnpacking)) {
			product.setIsAntiUnpacking(isAntiUnpacking);
		} else {
			product.setIsAntiUnpacking("N");
		}
		if (StringUtils.isNotBlank(graphicType)) {
			product.setGraphicType(graphicType);
		} else {
			product.setGraphicType("S");
		}
		if (StringUtils.isNotBlank(isValidateNum)) {
			product.setIsValidateNum(isValidateNum);
		} else {
			product.setIsValidateNum("N");
		}
		if (StringUtils.isNotBlank(useDeliveryDay)) {
			product.setUseDeliveryDay(useDeliveryDay);
		} else {
			product.setUseDeliveryDay("N");
		}
		product.setDeliveryDay(deliveryDay);
		product.setSupplierId(editsupplier);
		if (Arrays.asList("010000", "010001").contains(editsupplier)) {
			if (StringUtils.equalsIgnoreCase("Y", product.getIsScm())) {
				addActionError("若供应商为万美供应商，采购模式不可为转单");
				return "edit";
			}
			if (StringUtils.isNotBlank(editTwSupplier)) {
				product.setTwSupplierId(editTwSupplier);
			} else {
				product.setTwSupplierId("");
			}
		}
		product.setProductBrand(editbrand);
		product.setPmID(pm);
		product.setOrganizationPath(organization);
		product.setProductKeyword(keyword);
		product.setIsDelete(productAttribute);
		product.setReturnRule(returnRule);
		product.setNmMustOrderBuy(nmMustOrderBuy);
		product.setPickupQty(0);// 非n选m的商品一律设为0
		product.setProductStatus("PRD500");
		product.setProductBrief(brief);
		product.setProductDescription(description);
		product.setProductDetails(details);
		if (StringUtils.isNotBlank(scmNotice)) {
			product.setScmNotice(scmNotice);
		}
		if (StringUtils.equals("1", type)) {// 预购商品要填预计到货日
			product.setExpectShipDate(format.parse(expectShipDate));
		} else {
			product.setExpectShipDate(null);
		}
		if (StringUtils.isBlank(prpsShelfPrice)) {
			product.setPrpsShelfPrice(new BigDecimal(0).setScale(2, BigDecimal.ROUND_FLOOR));
		} else {
			product.setPrpsShelfPrice(new BigDecimal(prpsShelfPrice).setScale(2, BigDecimal.ROUND_FLOOR));
		}
		if (StringUtils.isNotBlank(orderNotice)) {
			product.setProductOrderNotice(orderNotice);
		}

		if (StringUtils.isNotBlank(showSeq)) {
			product.setShowSeq(Integer.parseInt(showSeq));
		}
		if (StringUtils.isNotBlank(channelFirm)) {
			product.setChannelFirm(channelFirm);
		}
		/* 处理馆长推荐 */
		if (StringUtils.equalsIgnoreCase(flag16, "Y")) {
			productPromotionFlag.setFlag16(flag16);
		} else {
			productPromotionFlag.setFlag16(null);
		}
		product.setProductPromotionFlag(productPromotionFlag);

		/* 商品分身 */
		String[] splitData = StringUtils.split(finalAddOnData, ";");

		editProductCategories = new ArrayList<ProductCategory>();
		ProductCategory oldpc = null;
		ProductCategory pc = null;
		Category category = null;

		for (int i = 0; i < splitData.length; i++) {
			String[] sUpdate = StringUtils.split(splitData[i], ",");
			category = categoryService.getCategoryNonePermission(Long.parseLong(sUpdate[0]));
			Object[] pcObj = baseMgr.queryByHql("from ProductCategory where categoryId = ? and productId = ? ", new Object[] {
					Long.valueOf(sUpdate[0]), product.getProductId() });

			if (null != pcObj && pcObj.length > 0) {
				oldpc = (ProductCategory) pcObj[0];
			}
			pc = new ProductCategory();
			if (null != oldpc) {
				pc.setShowSeq(oldpc.getShowSeq());
			} else {
				pc.setShowSeq(Integer.parseInt(sUpdate[1]));
			}
			pc.setProductId(product.getProductId());
			pc.setCategoryId(Long.parseLong(sUpdate[0]));
			pc.setCategoryPath(category.getCategoryPath());
			pc.setCategoryName(category.getName());
			editProductCategories.add(pc);
		}
		product.setProductCategories(editProductCategories);
		product = product2Service.saveProductPage(product);
		// 新增/修改商品
		productId = product.getProductId();
		if ("next".equalsIgnoreCase(saveFlag)) {
			return spec();
		} else {
			addActionMessage("储存完成");
			return edit();
		}
	}

	public void setAttributeMenu(Menu attributeMenu) {
		this.attributeMenu = attributeMenu;
	}

	/**
	 * @param band the band to set
	 */
	public void setBrand(String brand) {
		this.brand = brand;
	}

	public void setBrandName(String brandName) {
		this.brandName = brandName;
	}

	public void setBrandParam(String brandParam) {
		this.brandParam = brandParam;
	}

	/**
	 * @param brands the brands to set
	 */
	public void setBrands(List<Brand> brands) {
		this.brands = brands;
	}

	/**
	 * @param brief the brief to set
	 */
	public void setBrief(String brief) {
		this.brief = brief;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	public void setCategoryId(String categoryId) {
		this.categoryId = categoryId;
	}

	public void setCategoryIdParam(String categoryIdParam) {
		this.categoryIdParam = categoryIdParam;
	}

	public void setCategoryLevel1Param(String categoryLevel1Param) {
		this.categoryLevel1Param = categoryLevel1Param;
	}

	public void setCategoryLevel2Param(String categoryLevel2Param) {
		this.categoryLevel2Param = categoryLevel2Param;
	}

	public void setCategoryResult(String categoryResult) {
		this.categoryResult = categoryResult;
	}

	/**
	 * @param categoryRoot the categoryRoot to set
	 */
	public void setCategoryRoot(List<Category> categoryRoot) {
		this.categoryRoot = categoryRoot;
	}

	/**
	 * @param categoryService the categoryService to set
	 */
	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	/**
	 * @param cost the cost to set
	 */
	public void setCost(String cost) {
		this.cost = cost;
	}

	/**
	 * @param delivertolerance the delivertolerance to set
	 */
	public void setDelivertolerance(String delivertolerance) {
		this.delivertolerance = delivertolerance;
	}

	/**
	 * @param delSelectedCategory the delSelectedCategory to set
	 */
	public void setDelSelectedCategory(String[] delSelectedCategory) {
		this.delSelectedCategory = delSelectedCategory;
	}

	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}

	/**
	 * @param details the details to set
	 */
	public void setDetails(String details) {
		this.details = details;
	}

	public void setEditbrand(String editbrand) {
		this.editbrand = editbrand;
	}

	/**
	 * @param editDeliverGeoRange the editDeliverGeoRange to set
	 */
	public void setEditDeliverGeoRange(String editDeliverGeoRange) {
		this.editDeliverGeoRange = editDeliverGeoRange;
	}

	/**
	 * @param editleadtime the editleadtime to set
	 */
	public void setEditleadtime(String editleadtime) {
		this.editleadtime = editleadtime;
	}

	public void setEditProductCategories(List<ProductCategory> editProductCategories) {
		this.editProductCategories = editProductCategories;
	}

	/**
	 * @param editsupplier the editsupplier to set
	 */
	public void setEditsupplier(String editsupplier) {
		this.editsupplier = editsupplier;
	}

	public void setExpectShipDate(String expectShipDate) {
		this.expectShipDate = expectShipDate;
	}

	public void setFileMap(Map<String, String> fileMap) {
		this.fileMap = fileMap;
	}

	public void setFinalAddOnData(String finalAddOnData) {
		this.finalAddOnData = finalAddOnData;
	}

	public void setFlag16(String flag16) {
		this.flag16 = flag16;
	}

	public void setFreightMenu(Menu freightMenu) {
		this.freightMenu = freightMenu;
	}

	public void setGroups(List<Group> groups) {
		this.groups = groups;
	}

	public void setGroupService(GroupService groupService) {
		this.groupService = groupService;
	}

	/**
	 * @param height the height to set
	 */
	public void setHeight(String height) {
		this.height = height;
	}

	public void setIsPmGroup(String isPmGroup) {
		this.isPmGroup = isPmGroup;
	}

	public void setJsonAddonProdSpec(String jsonAddonProdSpec) {
		this.jsonAddonProdSpec = jsonAddonProdSpec;
	}

	public void setJsonCategoryPath(String jsonCategoryPath) {
		this.jsonCategoryPath = jsonCategoryPath;
	}

	public void setJsonOrderNotice(String jsonOrderNotice) {
		this.jsonOrderNotice = jsonOrderNotice;
	}

	/**
	 * @param keyword the keyword to set
	 */
	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	/**
	 * @param length the length to set
	 */
	public void setLength(String length) {
		this.length = length;
	}

	public void setMainCategoryId(String mainCategoryId) {
		this.mainCategoryId = mainCategoryId;
	}

	public void setMapRootCategories(Map<String, String> mapRootCategories) {
		this.mapRootCategories = mapRootCategories;
	}

	/**
	 * @param maxpo the maxpo to set
	 */
	public void setMaxpo(String maxpo) {
		this.maxpo = maxpo;
	}

	public void setMenuService(DomainService<Menu> menuService) {
		this.menuService = menuService;
	}

	/**
	 * @param minpo the minpo to set
	 */
	public void setMinpo(String minpo) {
		this.minpo = minpo;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	public void setOrderNotice(String orderNotice) {
		this.orderNotice = orderNotice;
	}

	/**
	 * @param organization the organization to set
	 */
	public void setOrganization(String organization) {
		this.organization = organization;
	}

	/**
	 * @param pager the pager to set
	 */
	public void setPager(SimplePager pager) {
		this.pager = pager;
	}

	/**
	 * @param pm the pm to set
	 */
	public void setPm(String pm) {
		this.pm = pm;
	}

	public void setPmIdParam(String pmIdParam) {
		this.pmIdParam = pmIdParam;
	}

	/**
	 * @param prdtDelete the prdtDelete to set
	 */
	public void setPrdtDelete(String[] prdtDelete) {
		this.prdtDelete = prdtDelete;
	}

	/**
	 * @param price the price to set
	 */
	public void setPrice(String price) {
		this.price = price;
	}

	/**
	 * @param product the product to set
	 */
	public void setProduct(Product product) {
		this.product = product;
	}

	public void setProductAttribute(String productAttribute) {
		this.productAttribute = productAttribute;
	}

	public void setProductAttributeParam(String productAttributeParam) {
		this.productAttributeParam = productAttributeParam;
	}

	public void setProductCategories(List<ProductCategory> productCategories) {
		this.productCategories = productCategories;
	}

	public void setProductCategoryMap(Map<Long, String> productCategoryMap) {
		this.productCategoryMap = productCategoryMap;
	}

	/**
	 * @param productId the productId to set
	 */
	public void setProductId(String productId) {
		this.productId = productId;
	}

	/**
	 * @param productIdParam the productIdParam to set
	 */
	public void setProductIdParam(String productIdParam) {
		this.productIdParam = productIdParam;
	}

	/**
	 * @param productNameParam the productNameParam to set
	 */
	public void setProductNameParam(String productNameParam) {
		this.productNameParam = productNameParam;
	}

	public void setProductPromotionFlag(ProductPromotionFlag productPromotionFlag) {
		this.productPromotionFlag = productPromotionFlag;
	}

	/**
	 * @param products the products to set
	 */
	public void setProducts(List<Product> products) {
		this.products = products;
	}

	/**
	 * @param productService the productService to set
	 */
	public void setProduct2Service(Product2Service product2Service) {
		this.product2Service = product2Service;
	}

	public void setProductStParam(String productStParam) {
		this.productStParam = productStParam;
	}

	public void setProductTypeParam(String productTypeParam) {
		this.productTypeParam = productTypeParam;
	}

	/**
	 * @param returnable the returnable to set
	 */
	public void setReturnable(String returnable) {
		this.returnable = returnable;
	}

	/**
	 * @param returnpickup the returnpickup to set
	 */
	public void setReturnpickup(String returnpickup) {
		this.returnpickup = returnpickup;
	}

	public void setRootCategories(List<Category> rootCategories) {
		this.rootCategories = rootCategories;
	}

	/**
	 * @param rsmap the rsmap to set
	 */
	public void setRsmap(Map<String, String> rsmap) {
		this.rsmap = rsmap;
	}

	/**
	 * @param selectedcategories the selectedcategories to set
	 */
	public void setSelectedcategories(List<ProductCategory> selectedcategories) {
		this.selectedcategories = selectedcategories;
	}

	public void setSetMainSupplier(String setMainSupplier) {
		this.setMainSupplier = setMainSupplier;
	}

	/**
	 * @param showSelectedCategory the showSelectedCategory to set
	 */
	public void setShowSelectedCategory(String showSelectedCategory) {
		this.showSelectedCategory = showSelectedCategory;
	}

	public void setShowSeq(String showSeq) {
		this.showSeq = showSeq;
	}

	public void setShowSpecSeq(String[] showSpecSeq) {
		this.showSpecSeq = showSpecSeq;
	}

	/**
	 * @param spcBarCode the spcBarCode to set
	 */
	public void setSpcBarCode(String[] spcBarCode) {
		this.spcBarCode = spcBarCode;
	}

	/**
	 * @param spcCode the spcCode to set
	 */
	public void setSpcCode(String[] spcCode) {
		this.spcCode = spcCode;
	}

	/**
	 * @param spcDelete the spcDelete to set
	 */
	public void setSpcDelete(String[] spcDelete) {
		this.spcDelete = spcDelete;
	}

	/**
	 * @param spcId the spcId to set
	 */
	public void setSpcId(String[] spcId) {
		this.spcId = spcId;
	}

	/**
	 * @param spcMaxCountPerOrder the spcMaxCountPerOrder to set
	 */
	public void setSpcMaxCountPerOrder(String[] spcMaxCountPerOrder) {
		this.spcMaxCountPerOrder = spcMaxCountPerOrder;
	}

	/**
	 * @param spcMinCountPerOrder the spcMinCountPerOrder to set
	 */
	public void setSpcMinCountPerOrder(String[] spcMinCountPerOrder) {
		this.spcMinCountPerOrder = spcMinCountPerOrder;
	}

	/**
	 * @param spcName the spcName to set
	 */
	public void setSpcName(String[] spcName) {
		this.spcName = spcName;
	}

	// /**
	// * @param spcReverseInventory the spcReverseInventory to set
	// */
	// public void setSpcReverseInventory(String[] spcReverseInventory) {
	// this.spcReverseInventory = spcReverseInventory;
	// }

	/**
	 * @param spcSafeInventory the spcSafeInventory to set
	 */
	public void setSpcSafeInventory(String[] spcSafeInventory) {
		this.spcSafeInventory = spcSafeInventory;
	}

	/**
	 * @param specification the specification to set
	 */
	public void setSpecification(Specification specification) {
		this.specification = specification;
	}

	/**
	 * @param specificationinventory the specificationinventory to set
	 */
	public void setSpecificationinventory(SpecificationInventory specificationinventory) {
		this.specificationinventory = specificationinventory;
	}

	/**
	 * @param specificationinventorys the specificationinventorys to set
	 */
	public void setSpecificationinventorys(List<SpecificationInventory> specificationinventorys) {
		this.specificationinventorys = specificationinventorys;
	}

	public void setSpecStatusMenu(Menu specStatusMenu) {
		this.specStatusMenu = specStatusMenu;
	}

	public void setSpecStatusParam(String specStatusParam) {
		this.specStatusParam = specStatusParam;
	}

	public void setSpecSubStatusMenu(Menu specSubStatusMenu) {
		this.specSubStatusMenu = specSubStatusMenu;
	}

	public void setStockReports(List<Object> stockReports) {
		this.stockReports = stockReports;
	}

	public void setSupplierApplyService(SupplierApplyService supplierApplyService) {
		this.supplierApplyService = supplierApplyService;
	}

	public void setSupplierCompanyName(String supplierCompanyName) {
		this.supplierCompanyName = supplierCompanyName;
	}

	/**
	 * @param supplierDelete the supplierDelete to set
	 */
	public void setSupplierDelete(String[] supplierDelete) {
		this.supplierDelete = supplierDelete;
	}

	public void setSupplierParam(String supplierParam) {
		this.supplierParam = supplierParam;
	}

	/**
	 * @param tax the tax to set
	 */
	public void setTax(String tax) {
		this.tax = tax;
	}

	/**
	 * @param temperature the temperature to set
	 */
	public void setTemperature(String temperature) {
		this.temperature = temperature;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}

	/**
	 * @param unit the unit to set
	 */
	public void setUnit(String unit) {
		this.unit = unit;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/**
	 * @param virtual the virtual to set
	 */
	public void setVirtual(String virtual) {
		this.virtual = virtual;
	}

	/**
	 * @param volume the volume to set
	 */
	public void setVolume(String volume) {
		this.volume = volume;

	}

	/**
	 * @param weight the weight to set
	 */
	public void setWeight(String weight) {
		this.weight = weight;
	}

	/**
	 * @param width the width to set
	 */
	public void setWidth(String width) {
		this.width = width;
	}

	/* 編輯商品Spec */
	public String spec() throws Exception {
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		} else {
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
			if (StringUtils.isBlank(product.getMainSpecName()) && StringUtils.isBlank(product.getSecondSpecName())) {
				tempProdSpec = "";
			} else {
				// 查詢主規格
				CommonCriteria crit = new CommonCriteria();
				crit.addEq("productId", productId);
				if (StringUtils.isBlank(specStatusParam)) {
					specStatusParam = "A";
				}
				if (!StringUtils.equalsIgnoreCase("A", specStatusParam)) {
					crit.addEq("isDelete", specStatusParam);
				}
				majors = product2Service.getSpecificationMajorList(crit, new String[] { "showSeq asc" });

				// 查庫存
				crit = new CommonCriteria();
				crit.addEq("productId", productId);
				List<SpecificationInventory> specInvs = product2Service.getSpecificationInventory(crit);
				List<Integer> nums = null;
				for (SpecificationInventory inv : specInvs) {
					nums = new ArrayList<Integer>();
					nums.add(0, inv.getAvailableInventory());
					nums.add(1, inv.getSoldInventory());
					nums.add(2, inv.getCancelInventory());
					specInvMap.put(inv.getSpecId(), nums);
				}
			}
			// 缺货登记数
			stockQty = product2Service.getStockOutByProductId(productId);
			initSpecParam();
		}
		nowStep = "2";
		return "spec";
	}

	/**
	 * 储存商品主檔的规格资料
	 * 
	 * @return
	 * @throws Exception
	 */
	public String saveProdSpec() throws Exception {
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		} else {
			if (null == product || !StringUtils.equals(productId, product.getProductId())) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
		}
		product.setHotSaleInventory(hotSaleInventory);
		product.setMainCodeLabel(mainCodeLabel);
		product.setSecondCodeLabel(secondCodeLabel);
		if (StringUtils.isNotBlank(arrivalDate)) {
			product.setArrivalDate(format.parse(arrivalDate));
		}
		product = product2Service.save(product);
		productId = product.getProductId();
		addActionMessage("储存完成");

		if ((StringUtils.isNotBlank(mainSpecName) && StringUtils.isNotBlank(secondSpecName))
				|| product.getActivateSpecMajors().size() == 0) {
			return addSpec();
		} else {
			return spec();
		}
	}

	public String addSpec() throws Exception {
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		} else {
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
		}

		if (StringUtils.equals("spec", addType)) {
			tmpSecondMap = new HashMap<String, String>();
			for (int i = 0; i < addMajorSel.length; i++) {
				SpecificationMajor major = product.getMajorMap().get(addMajorSel[i]);
				if (null != major && !major.getJsonDetail().contains("\"specName\":\"" + secondSpecName + "\"")) {
					tmpSecondMap.put(addMajorSel[i], secondSpecName);
				}
			}
		}
		tempProdSpec = "Y";
		// 查詢主規格
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("productId", productId);
		if (StringUtils.isBlank(specStatusParam)) {
			specStatusParam = "A";
		}
		if (!StringUtils.equalsIgnoreCase("A", specStatusParam)) {
			crit.addEq("isDelete", specStatusParam);
		}
		majors = product2Service.getSpecificationMajorList(crit, new String[] { "showSeq asc" });

		// 查庫存
		crit = new CommonCriteria();
		crit.addEq("productId", productId);
		List<SpecificationInventory> specInvs = product2Service.getSpecificationInventory(crit);
		List<Integer> nums = null;
		for (SpecificationInventory inv : specInvs) {
			nums = new ArrayList<Integer>();
			nums.add(0, inv.getAvailableInventory());
			nums.add(1, inv.getSoldInventory());
			nums.add(2, inv.getCancelInventory());
			specInvMap.put(inv.getSpecId(), nums);
		}
		// 缺货登记数
		stockQty = product2Service.getStockOutByProductId(productId);
		return "spec";
	}

	/**
	 * 储存主规格资料
	 * 
	 * @return
	 * @throws Exception
	 */
	public String saveMajor() throws Exception {
		HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(
				ServletActionContext.HTTP_RESPONSE);
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		} else {
			if (null == product || !StringUtils.equals(productId, product.getProductId())) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
		}

		CommonCriteria crit = new CommonCriteria();
		crit.addEq("productId", productId);
		if (StringUtils.isBlank(specStatusParam)) {
			specStatusParam = "A";
		}
		if (!StringUtils.equalsIgnoreCase("A", specStatusParam)) {
			crit.addEq("isDelete", specStatusParam);
		}

		Product product = product2Service.get(productId);
		Map<String, SpecificationMajor> majorMap = new HashMap<String, SpecificationMajor>();
		int j = 1;
		for (int i = 0; i < spcName.length; i++) {
			if (StringUtils.isBlank(spcId[i])) {// save spec
				Specification spec = new Specification();
				spec.setSpecificationName(spcMajorName[i].replaceAll("／", "/").replaceAll(",", "，") + EcConstant.SPEC_SYMBOL
						+ spcName[i].replaceAll("／", "/").replaceAll(",", "，"));
				spec.setBarCode(spcBarCode[i]);
				spec.setSpecCode(spcCode[i]);
				if (StringUtils.isNotBlank(spcMaxCountPerOrder[i]) && StringUtils.isNotBlank(spcMinCountPerOrder[i])
						&& StringUtils.isNotBlank(spcSafeInventory[i])) {
					spec.setMaxCountPerOrder(Integer.parseInt(spcMaxCountPerOrder[i]));
					spec.setMinCountPerOrder(Integer.parseInt(spcMinCountPerOrder[i]));
					spec.setSafeInventory(Integer.parseInt(spcSafeInventory[i]));
				}
				spec.setIsDelete("N");
				spec.setProductId(productId);
				spec.setShowSeq(j);
				product.getSpecifications().add(spec);
			} else {// update spec
				for (Specification spec : product.getSpecifications()) {
					if (null != spec.getSpecificationId() && spec.getSpecificationId().toString().equals(spcId[i])) {
						spec.setIsDelete("N");
						spec.setSpecificationName(spec.getSpecificationName().replaceAll(",", "，"));// 移除脫逸字元/n/r(在entity處理)
						spec.setBarCode(spcBarCode[i]);
						spec.setSpecCode(spcCode[i]);
						spec.setMaxCountPerOrder(Integer.parseInt(spcMaxCountPerOrder[i]));
						spec.setMinCountPerOrder(Integer.parseInt(spcMinCountPerOrder[i]));
						spec.setSafeInventory(Integer.parseInt(spcSafeInventory[i]));
						spec.setShowSeq(j);
					}
				}
			}
			j++;
		}
		SpecificationMajor updMajor = null;
		for (int i = 0; i < majorId.length; i++) {
			if (StringUtils.isBlank(majorId[i])) {
				updMajor = new SpecificationMajor();
				updMajor.setMainSpecName(majorName[i]);
				updMajor.setProductId(product.getProductId());
				updMajor.setIsDelete("N");
				updMajor.setIsCover("N");
				majorMap.put(majorName[i], updMajor);
			} else {
				updMajor = product.getMajorMap().get(majorName[i]);
				if (null != updMajor) {
					updMajor.setIsDelete("N");
					majorMap.put(updMajor.getMainSpecName(), updMajor);
				}
			}
		}
		// delete main spec
		if (null != mainDel) {
			for (int i = 0; i < mainDel.length; i++) {
				for (SpecificationMajor major : product.getSpecMajors()) {
					if (major.getMainSpecId().toString().equals(mainDel[i])) {
						major.setIsDelete("Y");
						majorMap.put(major.getMainSpecName(), major);
					}
				}
			}
		}

		if (null != secondDel) { // delete spec
			for (int i = 0; i < secondDel.length; i++) {
				for (Specification spec : product.getSpecifications()) {
					if (null != spec.getSpecificationId() && spec.getSpecificationId().toString().equals(secondDel[i])) {
						spec.setIsDelete("Y");
					}
				}
			}
		}

		if (!majorMap.isEmpty() && majorMap.size() > 0) {
			product.setMajorMap(majorMap);
		}
		product.setTmpSepcIsDelete(specStatusParam);
		if (StringUtils.isBlank(product.getMainSpecName())) {
			product.setMainSpecName(mainSpecName);
		} else if (StringUtils.isNotBlank(mainSpecName)
				&& !Arrays.asList(product.getMainSpecName().split(",")).contains(mainSpecName)) {
			product.setMainSpecName(product.getMainSpecName() + "," + mainSpecName);
		}
		if (StringUtils.isBlank(product.getSecondSpecName())) {
			product.setSecondSpecName(secondSpecName);
		} else if (StringUtils.isNotBlank(secondSpecName)
				&& !Arrays.asList(product.getSecondSpecName().split(",")).contains(secondSpecName)) {
			product.setSecondSpecName(product.getSecondSpecName() + "," + secondSpecName);
		}
		if (product.getStepFlag() == 2) {
			product.setStepFlag(3);
		}
		product = product2Service.saveOrUpdateProduct(product, true);
		product.sortSpecList();

		if ("next".equalsIgnoreCase(saveFlag)) {
			response.sendRedirect(ServerValue.getMidContextPath() + "/image2/edit.do?productId=" + product.getProductId());
		} else {
			addActionMessage("储存完成");
			return spec();
		}
		return spec();
	}

	void initSpecParam() {
		secondDel = null;
		mainDel = null;
		tmpSecondMap = null;
		addType = null;
		mainSpecName = null;
		secondSpecName = null;
	}

	/**
	 * 编辑规格
	 * 
	 * @return
	 * @throws Exception
	 */
	public String editSecondSpec() throws Exception {
		if (StringUtils.isBlank(productId) || StringUtils.length(productId) != 8 || !NumberUtils.isNumber(productId)) {
			addActionError("传入参数错误");
			return list();
		} else {
			product = product2Service.get(productId);
			if (null == product) {
				addActionError("查无商品资料(或无该权限查看)");
				return list();
			}
		}

		// 查庫存
		CommonCriteria crit = new CommonCriteria();
		crit.addEq("productId", productId);
		List<SpecificationInventory> specInvs = product2Service.getSpecificationInventory(crit);

		if (StringUtils.equals("spec", addType)) {
			// 查spec資料
			Object[] obj = new Object[addMajorSel.length + 1];
			obj[0] = productId;
			StringBuffer sb = new StringBuffer("(");
			int i = 1;
			for (String addMajor : addMajorSel) {
				sb.append("specificationName like ? ");
				obj[i] = addMajor;
				if (i < addMajorSel.length) {
					sb.append(" or ");
				}
				i++;
			}
			sb.append(" ) ");

			specifications = baseMgr.queryByHql("from Specification where productId = ? and " + sb.toString(), obj);
		}

		List<Integer> nums = null;
		for (SpecificationInventory inv : specInvs) {
			nums = new ArrayList<Integer>();
			nums.add(0, inv.getAvailableInventory());
			nums.add(1, inv.getSoldInventory());
			nums.add(2, inv.getCancelInventory());
			specInvMap.put(inv.getSpecId(), nums);
		}
		return "editSecondSpec";
	}

	/**
	 * 缺货报表
	 * 
	 * @return
	 * @throws CoreException
	 */
	public String stockOutReport() throws CoreException {
		return "stockOutReport";
	}

	/**
	 * 缺货报表
	 * 
	 * @return
	 * @throws CoreException
	 */
	public String stockOutReportSearch() throws CoreException {
		User user = AdminHelper.getUser();
		if (user.getGroup().getCode().indexOf("A-20") < 0) {
			isPmGroup = "N";
		} else {
			isPmGroup = "Y";
		}
		if (isPmGroup.equals("Y")) {
			if (StringUtils.isBlank(categoryIdParam) && StringUtils.isBlank(productStParam) && StringUtils.isBlank(pmIdParam)) {
				addActionError("产品部门必须要输入其中一个条件");
			} else {
				stockReports = product2Service.getStockOutReport(Long
						.parseLong(StringUtils.isNotBlank(categoryIdParam) ? categoryIdParam : "0"), productStParam, pmIdParam,
						productIdParam, productNameParam, supplierParam, stockNotify, startStockQty, endStockQty);
			}
		} else {
			stockReports = product2Service.getStockOutReport(Long
					.parseLong(StringUtils.isNotBlank(categoryIdParam) ? categoryIdParam : "0"), productStParam, pmIdParam,
					productIdParam, productNameParam, supplierParam, stockNotify, startStockQty, endStockQty);
		}

		return "stockOutReport";
	}

	/**
	 * 缺货报表编辑预计到货日
	 * 
	 * @return
	 * @throws CoreException
	 * @throws ParseException
	 */
	public String stockOutReportSave() throws CoreException, ParseException {
		if (!ArrayUtils.isEmpty(productIdBoxs)) {
			for (String productId : productIdBoxs) {
				product = product2Service.get(productId);
				product.setArrivalDate(format.parse(arrivalDate));
				product2Service.update(product);
			}
		}
		return stockOutReportSearch();

	}

	// 已销售未出货的库存查询
	public String orderNotShipping() throws Exception {
		product = product2Service.get(productId);
		orderNoShippingList = product2Service.orderNotShipping(productId, specificId);
		return "orderNotShipping";

	}

	public String updateArrivalDate() throws Exception {
		if (StringUtils.isNotBlank(arrivalDate)) {
			product = product2Service.get(productId);
			product.setArrivalDate(format.parse(arrivalDate));
			product2Service.update(product);
		}
		return spec();
	}

	/* 上傳商品圖片 */
	public String upload() throws Exception {
		return "upload";
	}

	/**
	 * 导入描述图
	 * 
	 * @return
	 * @throws Exception
	 */
	public String loadDescImg() throws Exception {
		if (StringUtils.isNotBlank(productId)) {
			CommonCriteria crit = new CommonCriteria();
			crit.addEq("productId", productId);
			crit.addEq("type", "DESC");
			crit.addNe("isDelete", "Y");
			descImgs = imageService.getList(0, -1, crit, new String[] { "showSeq asc" });
		}
		return "descImg";
	}

	public String getIsScm() {
		return isScm;
	}

	public void setIsScm(String isScm) {
		this.isScm = isScm;
	}

	public String getScmNotice() {
		return scmNotice;
	}

	public void setScmNotice(String scmNotice) {
		this.scmNotice = scmNotice;
	}

	public ProductSupplierApproveService getProductSupplierApproveService() {
		return productSupplierApproveService;
	}

	public void setProductSupplierApproveService(ProductSupplierApproveService productSupplierApproveService) {
		this.productSupplierApproveService = productSupplierApproveService;
	}

	public String getHr24Result() {
		return hr24Result;
	}

	public void setHr24Result(String hr24Result) {
		this.hr24Result = hr24Result;
	}

	public Menu getExpireManageMenu() {
		return expireManageMenu;
	}

	public void setExpireManageMenu(Menu expireManageMenu) {
		this.expireManageMenu = expireManageMenu;
	}

	public Menu getReturnRuleMenu() {
		return returnRuleMenu;
	}

	public void setReturnRuleMenu(Menu returnRuleMenu) {
		this.returnRuleMenu = returnRuleMenu;
	}

	public String getExpireManage() {
		return expireManage;
	}

	public void setExpireManage(String expireManage) {
		this.expireManage = expireManage;
	}

	public SupplierApply getSp() {
		return sp;
	}

	public void setSp(SupplierApply sp) {
		this.sp = sp;
	}

	public String getSpResult() {
		return spResult;
	}

	public void setSpResult(String spResult) {
		this.spResult = spResult;
	}

	public String getIsAntiUnpacking() {
		return isAntiUnpacking;
	}

	public void setIsAntiUnpacking(String isAntiUnpacking) {
		this.isAntiUnpacking = isAntiUnpacking;
	}

	public List<AddOnProduct> getAddons() {
		return addons;
	}

	public void setAddons(List<AddOnProduct> addons) {
		this.addons = addons;
	}

	public List<AddOnProduct> getNms() {
		return nms;
	}

	public void setNms(List<AddOnProduct> nms) {
		this.nms = nms;
	}

	public int getApproveSize() {
		return approveSize;
	}

	public void setApproveSize(int approveSize) {
		this.approveSize = approveSize;
	}

	public List<AddOnProduct> getAddonsMain() {
		return addonsMain;
	}

	public void setAddonsMain(List<AddOnProduct> addonsMain) {
		this.addonsMain = addonsMain;
	}

	public boolean isChkHasInventory() {
		return chkHasInventory;
	}

	public void setChkHasInventory(boolean chkHasInventory) {
		this.chkHasInventory = chkHasInventory;
	}

	public String getGraphicType() {
		return graphicType;
	}

	public void setGraphicType(String graphicType) {
		this.graphicType = graphicType;
	}

	public String getPrpsShelfPrice() {
		return prpsShelfPrice;
	}

	public void setPrpsShelfPrice(String prpsShelfPrice) {
		this.prpsShelfPrice = prpsShelfPrice;
	}

	public String getCopy() {
		return copy;
	}

	public void setCopy(String copy) {
		this.copy = copy;
	}

	public boolean isStockNotify() {
		return stockNotify;
	}

	public void setStockNotify(boolean stockNotify) {
		this.stockNotify = stockNotify;
	}

	public int getStartStockQty() {
		return startStockQty;
	}

	public int getEndStockQty() {
		return endStockQty;
	}

	public void setStartStockQty(int startStockQty) {
		this.startStockQty = startStockQty;
	}

	public void setEndStockQty(int endStockQty) {
		this.endStockQty = endStockQty;
	}

	public String[] getProductIdBoxs() {
		return productIdBoxs;
	}

	public void setProductIdBoxs(String[] productIdBoxs) {
		this.productIdBoxs = productIdBoxs;
	}

	public String getArrivalDate() {
		return arrivalDate;
	}

	public void setArrivalDate(String arrivalDate) {
		this.arrivalDate = arrivalDate;
	}

	public int getStockQty() {
		return stockQty;
	}

	public void setStockQty(int stockQty) {
		this.stockQty = stockQty;
	}

	public String getIsValidateNum() {
		return isValidateNum;
	}

	public void setIsValidateNum(String isValidateNum) {
		this.isValidateNum = isValidateNum;
	}

	public String getUseDeliveryDay() {
		return useDeliveryDay;
	}

	public int getDeliveryDay() {
		return deliveryDay;
	}

	public void setUseDeliveryDay(String useDeliveryDay) {
		this.useDeliveryDay = useDeliveryDay;
	}

	public void setDeliveryDay(int deliveryDay) {
		this.deliveryDay = deliveryDay;
	}

	public String getUserPermissions() {
		return userPermissions;
	}

	public void setUserPermissions(String userPermissions) {
		this.userPermissions = userPermissions;
	}

	public String getEditTwSupplier() {
		return editTwSupplier;
	}

	public void setEditTwSupplier(String editTwSupplier) {
		this.editTwSupplier = editTwSupplier;
	}

	public String getTwSupplierCompanyName() {
		return twSupplierCompanyName;
	}

	public void setTwSupplierCompanyName(String twSupplierCompanyName) {
		this.twSupplierCompanyName = twSupplierCompanyName;
	}

	public String getScmParam() {
		return scmParam;
	}

	public void setScmParam(String scmParam) {
		this.scmParam = scmParam;
	}

	public String getSpecificId() {
		return specificId;
	}

	public void setSpecificId(String specificId) {
		this.specificId = specificId;
	}

	public List<Object> getOrderNoShippingList() {
		return orderNoShippingList;
	}

	public void setOrderNoShippingList(List<Object> orderNoShippingList) {
		this.orderNoShippingList = orderNoShippingList;
	}

	public Menu getOrderStMenu() {
		return orderStMenu;
	}

	public void setOrderStMenu(Menu orderStMenu) {
		this.orderStMenu = orderStMenu;
	}

	public String getDataSrcParam() {
		return dataSrcParam;
	}

	public void setDataSrcParam(String dataSrcParam) {
		this.dataSrcParam = dataSrcParam;
	}

	public String getTempCategoryFullPath() {
		return tempCategoryFullPath;
	}

	public void setTempCategoryFullPath(String tempCategoryFullPath) {
		this.tempCategoryFullPath = tempCategoryFullPath;
	}

	public String getMainCategoryPath() {
		return mainCategoryPath;
	}

	public void setMainCategoryPath(String mainCategoryPath) {
		this.mainCategoryPath = mainCategoryPath;
	}

	public List<Image> getDescImgs() {
		return descImgs;
	}

	public void setDescImgs(List<Image> descImgs) {
		this.descImgs = descImgs;
	}

	public String getSaveFlag() {
		return saveFlag;
	}

	public void setSaveFlag(String saveFlag) {
		this.saveFlag = saveFlag;
	}

	public Menu getMainLabelMenu() {
		return mainLabelMenu;
	}

	public Menu getSecondLabelMenu() {
		return secondLabelMenu;
	}

	public void setMainLabelMenu(Menu mainLabelMenu) {
		this.mainLabelMenu = mainLabelMenu;
	}

	public void setSecondLabelMenu(Menu secondLabelMenu) {
		this.secondLabelMenu = secondLabelMenu;
	}

	public int getHotSaleInventory() {
		return hotSaleInventory;
	}

	public void setHotSaleInventory(int hotSaleInventory) {
		this.hotSaleInventory = hotSaleInventory;
	}

	public String getMainLabel() {
		return mainLabel;
	}

	public String getSecondLabel() {
		return secondLabel;
	}

	public String getMainLabelDefine() {
		return mainLabelDefine;
	}

	public String getSecondLabelDefine() {
		return secondLabelDefine;
	}

	public String getMainSpecName() {
		return mainSpecName;
	}

	public String getSecondSpecName() {
		return secondSpecName;
	}

	public void setMainLabel(String mainLabel) {
		this.mainLabel = mainLabel;
	}

	public void setSecondLabel(String secondLabel) {
		this.secondLabel = secondLabel;
	}

	public void setMainLabelDefine(String mainLabelDefine) {
		this.mainLabelDefine = mainLabelDefine;
	}

	public void setSecondLabelDefine(String secondLabelDefine) {
		this.secondLabelDefine = secondLabelDefine;
	}

	public void setMainSpecName(String mainSpecName) {
		this.mainSpecName = mainSpecName;
	}

	public void setSecondSpecName(String secondSpecName) {
		this.secondSpecName = secondSpecName;
	}

	public Map<Long, List<Integer>> getSpecInvMap() {
		return specInvMap;
	}

	public void setSpecInvMap(Map<Long, List<Integer>> specInvMap) {
		this.specInvMap = specInvMap;
	}

	public String[] getMainShowSeq() {
		return mainShowSeq;
	}

	public String[] getMainDel() {
		return mainDel;
	}

	public void setMainShowSeq(String[] mainShowSeq) {
		this.mainShowSeq = mainShowSeq;
	}

	public void setMainDel(String[] mainDel) {
		this.mainDel = mainDel;
	}

	public String[] getMajorId() {
		return majorId;
	}

	public void setMajorId(String[] majorId) {
		this.majorId = majorId;
	}

	public List<SpecificationMajor> getMajors() {
		return majors;
	}

	public void setMajors(List<SpecificationMajor> majors) {
		this.majors = majors;
	}

	public String getMainCodeLabel() {
		return mainCodeLabel;
	}

	public String getSecondCodeLabel() {
		return secondCodeLabel;
	}

	public void setMainCodeLabel(String mainCodeLabel) {
		this.mainCodeLabel = mainCodeLabel;
	}

	public void setSecondCodeLabel(String secondCodeLabel) {
		this.secondCodeLabel = secondCodeLabel;
	}

	public String getMainSpecId() {
		return mainSpecId;
	}

	public void setMainSpecId(String mainSpecId) {
		this.mainSpecId = mainSpecId;
	}

	public SpecificationMajor getMajor() {
		return major;
	}

	public void setMajor(SpecificationMajor major) {
		this.major = major;
	}

	public String[] getSecondDel() {
		return secondDel;
	}

	public void setSecondDel(String[] secondDel) {
		this.secondDel = secondDel;
	}

	public String[] getMajorName() {
		return majorName;
	}

	public void setMajorName(String[] majorName) {
		this.majorName = majorName;
	}

	public String[] getSpcMajorName() {
		return spcMajorName;
	}

	public void setSpcMajorName(String[] spcMajorName) {
		this.spcMajorName = spcMajorName;
	}

	public String getAddType() {
		return addType;
	}

	public void setAddType(String addType) {
		this.addType = addType;
	}

	public String[] getAddSpecSel() {
		return addSpecSel;
	}

	public String[] getAddMajorSel() {
		return addMajorSel;
	}

	public void setAddSpecSel(String[] addSpecSel) {
		this.addSpecSel = addSpecSel;
	}

	public void setAddMajorSel(String[] addMajorSel) {
		this.addMajorSel = addMajorSel;
	}

	public Object[] getSpecifications() {
		return specifications;
	}

	public void setSpecifications(Object[] specifications) {
		this.specifications = specifications;
	}

	public Map<String, String> getTmpSecondMap() {
		return tmpSecondMap;
	}

	public void setTmpSecondMap(Map<String, String> tmpSecondMap) {
		this.tmpSecondMap = tmpSecondMap;
	}

	public String getNowStep() {
		return nowStep;
	}

	public void setNowStep(String nowStep) {
		this.nowStep = nowStep;
	}

	public String getTempProdSpec() {
		return tempProdSpec;
	}

	public void setTempProdSpec(String tempProdSpec) {
		this.tempProdSpec = tempProdSpec;
	}

	public Menu getIsScmMenu() {
		return isScmMenu;
	}

	public void setIsScmMenu(Menu isScmMenu) {
		this.isScmMenu = isScmMenu;
	}

	public Menu getDataSrcMenu() {
		return dataSrcMenu;
	}

	public void setDataSrcMenu(Menu dataSrcMenu) {
		this.dataSrcMenu = dataSrcMenu;
	}

	public String codLimit() {
		if (StringUtils.isNotBlank(productAttributeParam) && StringUtils.isNotBlank(salePriceParam)) {
			shelfs = new ArrayList<ViewShelf>();
			shelfs = product2Service.getCODLimitProduct("N", productAttributeParam, salePriceParam);

		}
		return "codLimitList";
	}

	/**
	 * @return the salePriceParam
	 */
	public String getSalePriceParam() {
		return salePriceParam;
	}

	/**
	 * @param salePriceParam the salePriceParam to set
	 */
	public void setSalePriceParam(String salePriceParam) {
		this.salePriceParam = salePriceParam;
	}

	/**
	 * @return the shelfs
	 */
	public List<ViewShelf> getShelfs() {
		return shelfs;
	}

	/**
	 * @param shelfs the shelfs to set
	 */
	public void setShelfs(List<ViewShelf> shelfs) {
		this.shelfs = shelfs;
	}

	public String getCanUseCod() {
		return canUseCod;
	}

	public void setCanUseCod(String canUseCod) {
		this.canUseCod = canUseCod;
	}

	public String getChannelFirm() {
		return channelFirm;
	}

	public void setChannelFirm(String channelFirm) {
		this.channelFirm = channelFirm;
	}

	public String getNmMustOrderBuy() {
		return nmMustOrderBuy;
	}

	public void setNmMustOrderBuy(String nmMustOrderBuy) {
		this.nmMustOrderBuy = nmMustOrderBuy;
	}

	public String getSupplierChannel() {
		return supplierChannel;
	}

	public void setSupplierChannel(String supplierChannel) {
		this.supplierChannel = supplierChannel;
	}

	public String getCanUseCodYN() {
		return canUseCodYN;
	}

	public void setCanUseCodYN(String canUseCodYN) {
		this.canUseCodYN = canUseCodYN;
	}

	public String getLargeVolumeProduct() {
		return largeVolumeProduct;
	}

	public void setLargeVolumeProduct(String largeVolumeProduct) {
		this.largeVolumeProduct = largeVolumeProduct;
	}

	public String getProductGraphicType() {
		return productGraphicType;
	}

	public void setProductGraphicType(String productGraphicType) {
		this.productGraphicType = productGraphicType;
	}

	public String getReturnRule() {
		return returnRule;
	}

	public void setReturnRule(String returnRule) {
		this.returnRule = returnRule;
	}

	public String getSpecCodeParam() {
		return specCodeParam;
	}

	public void setSpecCodeParam(String specCodeParam) {
		this.specCodeParam = specCodeParam;
	}

}